package com.yunxi.order.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.yunxi.order.bean.Order;
import com.yunxi.order.properties.OrderProperties;
import com.yunxi.order.service.OrderService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * 订单相关 API
 *
 * @author: lidy
 * @date: 2025-01-17 11:18
 */
//@RefreshScope   // 动态刷新配置
@Slf4j
@RestController
@RequestMapping("/order")
public class OrderController {

    @Resource
    private OrderService orderService;

    @Resource
    private OrderProperties orderProperties;

//    @Value("${order.timeout}")
//    private String orderTimeout;
//
//    @Value("${order.auto-confirm}")
//    private String autoConfirm;

    @GetMapping("/config")
    public String getConfig() {
        return "orderTimeout:" + orderProperties.getTimeout() +
                ",autoConfirm:" + orderProperties.getAutoConfirm() +
                ",dbUrl:" + orderProperties.getDbUrl();
    }

    /**
     * 创建订单
     *
     * @param productId 商品id
     * @param userId    用户id
     * @return 商品信息
     */
    @GetMapping("/create")
    public Order createOrder(@RequestParam("productId") Long productId,
                             @RequestParam("userId") Long userId) {
        Order order = orderService.createOrder(productId, userId);
        return order;
    }

    /**
     * 秒杀
     *
     * @param productId 商品id
     * @param userId    用户id
     * @return 商品信息
     */
    @GetMapping("/seckill")
    @SentinelResource(value = "seckill-order", blockHandler = "seckillFallback")
    public Order seckill(@RequestParam("productId") Long productId,
                         @RequestParam("userId") Long userId) {
        Order order = orderService.createOrder(productId, userId);
        order.setId(Long.MAX_VALUE);
        return order;
    }

    /**
     * 限流后的回调方法
     * <p>
     * 需求1：每个用户秒杀 QPS 不得超过 1 （秒杀下单 userId 级别）
     * 携带此参数的流控，不带此参数的不流控
     * 需求2：6 号用户是 VVIP，不限制 QPS（例外情况）
     * 需求3：666号是下架商品，不允许访问
     *
     * @param productId 商品id
     * @param userId    用户id
     * @return 订单信息
     */
    public Order seckillFallback(Long productId,
                                 Long userId,
                                 Throwable throwable) {
        System.out.println("seckillFallback...");
        Order order = new Order();
        order.setId(productId);
        order.setNickname("异常信息：" + throwable.getClass());
        return order;
    }

    /**
     * 模拟读写数据库
     * 测试 sentinel 流控的 关联模式
     * 在大量写的情况下，对读限流
     */
    @GetMapping("/readDb")
    public String readDb() {
        log.info("readDb...");
        return "readDb success...";
    }

    @GetMapping("/writeDb")
    public String writeDb() {
        return "writeDb success...";
    }

}
